using MedicalReportAssistant.Models;
using MedicalReportAssistant.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.Collections.Generic;
using System.Windows;
using Microsoft.Extensions.Configuration;

namespace MedicalReportAssistant.Controllers
{
    public partial class MedicalReportController : ObservableObject
    {
        private readonly IOCRService _ocrService;
        private readonly IDeepSeekService _deepSeekService;
        private readonly IKnowledgeBaseService _knowledgeBaseService;
        private readonly ILogger<MedicalReportController> _logger;
        private readonly ICorrectionService _correctionService;
        private readonly DeepSeekService _deepSeekService;
        private readonly QwenCorrectionService _qwenCorrectionService;
        private readonly IConfiguration _configuration;

        [ObservableProperty]
        private MedicalReport _currentReport = new();

        [ObservableProperty]
        private bool _isProcessing;

        [ObservableProperty]
        private string _statusMessage = "就绪";

        public MedicalReportController(
            IOCRService ocrService,
            IDeepSeekService deepSeekService,
            IKnowledgeBaseService knowledgeBaseService,
            ILogger<MedicalReportController> logger,
            ICorrectionService correctionService,
            DeepSeekService deepSeekService,
            QwenCorrectionService qwenCorrectionService,
            IConfiguration configuration)
        {
            _ocrService = ocrService;
            _deepSeekService = deepSeekService;
            _knowledgeBaseService = knowledgeBaseService;
            _logger = logger;
            _correctionService = correctionService;
            _deepSeekService = deepSeekService;
            _qwenCorrectionService = qwenCorrectionService;
            _configuration = configuration;
        }

        [RelayCommand]
        public async Task CaptureAndRecognizeAsync()
        {
            try
            {
                IsProcessing = true;
                StatusMessage = "正在截图...";

                // 获取屏幕截图
                var screenRegion = GetScreenRegion();
                var recognizedText = await _ocrService.RecognizeTextFromScreenAsync(screenRegion);

                CurrentReport.OriginalText = recognizedText;
                CurrentReport.ProcessTime = DateTime.Now;
                StatusMessage = $"OCR识别完成，识别到 {recognizedText.Length} 个字符";

                _logger.LogInformation("OCR识别完成，文本长度: {Length}", recognizedText.Length);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "OCR识别失败");
                Views.LogWindow.Instance.LogError(ex.ToString());
                StatusMessage = $"OCR识别失败: {ex.Message}";
            }
            finally
            {
                IsProcessing = false;
            }
        }

        [RelayCommand]
        public async Task CorrectReportAsync()
        {
            if (string.IsNullOrWhiteSpace(CurrentReport.OriginalText))
            {
                StatusMessage = "请先进行OCR识别";
                return;
            }

            try
            {
                // 显示日志窗口
                var logWindow = Views.LogWindow.Instance;
                logWindow.Show();
                logWindow.Activate();

                IsProcessing = true;
                CurrentReport.IsProcessing = true;
                StatusMessage = "正在进行文本预处理...";

                // 清空之前的日志
                Console.WriteLine("=== 开始医学报告纠错分析 ===\n");
                Console.WriteLine($"处理时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}\n");

                // 步骤1：代码层面的文本预处理（去重等）
                var (preprocessedText, codeCorrections) = PreprocessAndRemoveRepetitions(CurrentReport.OriginalText);
                
                // 打印代码预处理结果
                Console.WriteLine("\n=== 代码预处理发现的问题 ===");
                if (codeCorrections.Any())
                {
                    foreach (var correction in codeCorrections)
                    {
                        Console.WriteLine($"原文：{correction.Original}");
                        Console.WriteLine($"修改：{correction.Corrected}");
                        Console.WriteLine($"原因：{correction.Reason}");
                        Console.WriteLine($"类型：{correction.Type}\n");
                    }
                }
                else
                {
                    Console.WriteLine("代码预处理未发现问题\n");
                }

                StatusMessage = "预处理完成，正在进行AI深度纠错...";

                // 步骤2：调用DeepSeek大模型进行深度纠错
                var aiCorrection = await CorrectMedicalReportAsync(preprocessedText);
                
                // 打印AI纠错结果
                Console.WriteLine("\n=== DeepSeek AI纠错结果 ===");
                Views.LogWindow.Instance.AppendText("\n=== DeepSeek AI纠错结果 ===\n");

                // 总是输出修正后的完整文本
                Console.WriteLine("修正后的完整文本：");
                Views.LogWindow.Instance.AppendText("修正后的完整文本：\n");
                Console.WriteLine("----------------------------------------");
                Views.LogWindow.Instance.AppendText("----------------------------------------\n");
                Console.WriteLine(aiCorrection.CorrectedText);
                Views.LogWindow.Instance.AppendText((aiCorrection.CorrectedText ?? "[无内容]") + "\n");
                Console.WriteLine("----------------------------------------\n");
                Views.LogWindow.Instance.AppendText("----------------------------------------\n\n");

                // 打印aiCorrection对象主要信息到日志
                Views.LogWindow.Instance.AppendText($"aiCorrection对象信息：\n");
                Views.LogWindow.Instance.AppendText($"Success: {aiCorrection.Success}\n");
                Views.LogWindow.Instance.AppendText($"OriginalText: {aiCorrection.OriginalText}\n");
                Views.LogWindow.Instance.AppendText($"CorrectedText: {aiCorrection.CorrectedText}\n");
                Views.LogWindow.Instance.AppendText($"Summary: {aiCorrection.Summary}\n");
                Views.LogWindow.Instance.AppendText($"Corrections数量: {(aiCorrection.Corrections == null ? 0 : aiCorrection.Corrections.Count)}\n");

                // 打印aiCorrection.Corrections对象信息到日志
                Views.LogWindow.Instance.AppendText($"aiCorrection.Corrections总数：{(aiCorrection.Corrections == null ? 0 : aiCorrection.Corrections.Count)}\n");
                if (aiCorrection.Corrections != null && aiCorrection.Corrections.Count > 0)
                {
                    int idx = 1;
                    foreach (var correction in aiCorrection.Corrections)
                    {
                        Views.LogWindow.Instance.AppendText($"--- Correction {idx} ---\n");
                        Views.LogWindow.Instance.AppendText($"原文：{correction.Original}\n");
                        Views.LogWindow.Instance.AppendText($"修改：{correction.Corrected}\n");
                        Views.LogWindow.Instance.AppendText($"原因：{correction.Reason}\n");
                        Views.LogWindow.Instance.AppendText($"类型：{correction.Type}\n");
                        idx++;
                    }
                }

                // 输出具体修改建议
                if (aiCorrection.Success && aiCorrection.Corrections != null && aiCorrection.Corrections.Any())
                {
                    Console.WriteLine("具体修改建议：");
                    Views.LogWindow.Instance.AppendText("具体修改建议：\n");
                    foreach (var correction in aiCorrection.Corrections)
                    {
                        Console.WriteLine($"原文：{correction.Original}");
                        Views.LogWindow.Instance.AppendText($"原文：{correction.Original}\n");
                        Console.WriteLine($"修改：{correction.Corrected}");
                        Views.LogWindow.Instance.AppendText($"修改：{correction.Corrected}\n");
                        Console.WriteLine($"原因：{correction.Reason}");
                        Views.LogWindow.Instance.AppendText($"原因：{correction.Reason}\n");
                        Console.WriteLine($"类型：{correction.Type}\n");
                        Views.LogWindow.Instance.AppendText($"类型：{correction.Type}\n\n");
                    }
                    Console.WriteLine($"总结：{aiCorrection.Summary}\n");
                    Views.LogWindow.Instance.AppendText($"总结：{aiCorrection.Summary}\n\n");
                }
                else
                {
                    Console.WriteLine("AI未发现需要修正的问题\n");
                    Views.LogWindow.Instance.AppendText("AI未发现需要修正的问题\n\n");
                    if (!string.IsNullOrWhiteSpace(aiCorrection.Summary))
                        Views.LogWindow.Instance.AppendText($"AI总结：{aiCorrection.Summary}\n\n");
                }

                // 步骤3：合并代码预处理的纠错和AI的纠错结果
                var finalResult = MergeCorrectionResults(codeCorrections, aiCorrection, preprocessedText);

                // 打印最终合并结果
                Console.WriteLine("\n=== 最终合并结果 ===");
                Console.WriteLine($"总计发现问题：{finalResult.Corrections.Count} 处");
                Console.WriteLine($"其中代码预处理：{codeCorrections.Count} 处");
                Console.WriteLine($"AI深度分析：{(aiCorrection.Success && aiCorrection.Corrections != null ? aiCorrection.Corrections.Count : 0)} 处\n");

                CurrentReport.CorrectedText = finalResult.CorrectedText;
                CurrentReport.CorrectionExplanation = finalResult.Summary;
                CurrentReport.Corrections = finalResult.Corrections;
                CurrentReport.ProcessTime = DateTime.Now;

                StatusMessage = $"纠错完成，共发现 {finalResult.Corrections.Count} 处问题";
                _logger.LogInformation("纠错完成，发现问题数: {Count}", finalResult.Corrections.Count);

                Views.LogWindow.Instance.AppendText($"ErrorMessage: {aiCorrection.ErrorMessage}\n");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "纠错分析失败");
                Views.LogWindow.Instance.LogError(ex.ToString());
                StatusMessage = $"纠错分析失败: {ex.Message}";
                Console.WriteLine($"\n错误：{ex.Message}\n");
            }
            finally
            {
                IsProcessing = false;
                CurrentReport.IsProcessing = false;
            }
        }

        [RelayCommand]
        public async Task<List<string>> SearchMedicalTermsAsync(string query)
        {
            try
            {
                var terms = await _knowledgeBaseService.SearchMedicalTermsAsync(query);
                _logger.LogInformation("搜索医学术语，查询: {Query}, 结果数: {Count}", query, terms.Count);
                return await Task.FromResult(terms);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "搜索医学术语失败");
                return await Task.FromResult(new List<string>());
            }
        }

        [RelayCommand]
        public void ClearReport()
        {
            CurrentReport = new MedicalReport();
            StatusMessage = "报告已清空";
        }

        [RelayCommand]
        public void CopyCorrectedText()
        {
            if (!string.IsNullOrEmpty(CurrentReport.CorrectedText))
            {
                System.Windows.Application.Current.Dispatcher.Invoke(() =>
                {
                    System.Windows.Clipboard.SetText(CurrentReport.CorrectedText);
                });
                StatusMessage = "已复制到剪贴板";
            }
        }

        private Rectangle GetScreenRegion()
        {
            // 这里可以实现区域选择功能
            // 暂时返回全屏区域
            return new Rectangle(0, 0, (int)System.Windows.SystemParameters.PrimaryScreenWidth, (int)System.Windows.SystemParameters.PrimaryScreenHeight);
        }

        private (string, List<CorrectionItem>) PreprocessAndRemoveRepetitions(string text)
        {
            var corrections = new List<CorrectionItem>();
            if (string.IsNullOrWhiteSpace(text))
            {
                return (text, corrections);
            }

            // 使用更鲁棒的方式分割行，并过滤空行
            var lines = text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                            .Select(line => line.Trim())
                            .Where(line => !string.IsNullOrWhiteSpace(line))
                            .ToList();

            var uniqueLines = new HashSet<string>();
            var cleanedTextBuilder = new StringBuilder();
            var previousLine = string.Empty;
            
            // 定义文本清理规则
            var rules = new[]
            {
                (pattern: @"\s+", replacement: " ", reason: "删除多余空格", isRegex: true),
                (pattern: @"[,，]\s*[,，]", replacement: "，", reason: "修正重复标点", isRegex: true),
                (pattern: @"[.。]\s*[.。]", replacement: "。", reason: "修正重复标点", isRegex: true)
            };

            foreach (var line in lines)
            {
                var processedLine = line;
                
                // 应用基本文本清理规则
                foreach (var rule in rules)
                {
                    var originalLine = processedLine;
                    if (rule.isRegex)
                    {
                        processedLine = Regex.Replace(processedLine, rule.pattern, rule.replacement);
                    }
                    else
                    {
                        processedLine = processedLine.Replace(rule.pattern, rule.replacement);
                    }
                    
                    if (originalLine != processedLine)
                    {
                        corrections.Add(new CorrectionItem
                        {
                            Original = originalLine,
                            Corrected = processedLine,
                            Reason = rule.reason,
                            Type = CorrectionType.Format
                        });
                    }
                }

                // 特殊处理：删除中文字符间的空格
                var originalWithSpaces = processedLine;
                processedLine = Regex.Replace(processedLine, @"([\u4e00-\u9fa5])\s+([\u4e00-\u9fa5])", "$1$2");
                if (originalWithSpaces != processedLine)
                {
                    corrections.Add(new CorrectionItem
                    {
                        Original = originalWithSpaces,
                        Corrected = processedLine,
                        Reason = "删除中文字符间的空格",
                        Type = CorrectionType.Format
                    });
                }

                // 检查与前一行的相似度
                var similarity = CalculateSimilarity(previousLine, processedLine);
                if (similarity > 0.8) // 相似度阈值可调整
                {
                    corrections.Add(new CorrectionItem
                    {
                        Original = processedLine,
                        Corrected = "[已删除相似行]",
                        Reason = "内容与前一行高度相似",
                        Type = CorrectionType.Logic
                    });
                    continue;
                }

                // 对比时忽略常见标点符号和空格，提高重复识别的准确率
                var comparableLine = Regex.Replace(processedLine, @"[\p{P}\s]", "");

                if (uniqueLines.Contains(comparableLine))
                {
                    corrections.Add(new CorrectionItem
                    {
                        Original = processedLine,
                        Corrected = "[已删除重复行]",
                        Reason = "内容与前文完全重复",
                        Type = CorrectionType.Logic
                    });
                }
                else
                {
                    uniqueLines.Add(comparableLine);
                    cleanedTextBuilder.AppendLine(processedLine);
                    previousLine = processedLine;
                }
            }

            var result = cleanedTextBuilder.ToString().Trim();
            
            // 如果预处理后文本为空，保留原文
            if (string.IsNullOrWhiteSpace(result))
            {
                return (text, corrections);
            }

            return (result, corrections);
        }

        // 计算两个字符串的相似度（使用Levenshtein距离）
        private double CalculateSimilarity(string s1, string s2)
        {
            if (string.IsNullOrEmpty(s1) || string.IsNullOrEmpty(s2)) return 0;
            
            var distance = LevenshteinDistance(s1, s2);
            var maxLength = Math.Max(s1.Length, s2.Length);
            return 1 - ((double)distance / maxLength);
        }

        private int LevenshteinDistance(string s1, string s2)
        {
            var matrix = new int[s1.Length + 1, s2.Length + 1];

            for (int i = 0; i <= s1.Length; i++)
                matrix[i, 0] = i;
            for (int j = 0; j <= s2.Length; j++)
                matrix[0, j] = j;

            for (int i = 1; i <= s1.Length; i++)
            {
                for (int j = 1; j <= s2.Length; j++)
                {
                    int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;
                    matrix[i, j] = Math.Min(
                        Math.Min(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1),
                        matrix[i - 1, j - 1] + cost
                    );
                }
            }

            return matrix[s1.Length, s2.Length];
        }

        private async Task<List<CorrectionItem>> ApplyLocalCorrectionsAsync(string text)
        {
            var rules = await _knowledgeBaseService.GetCorrectionRulesAsync();
            var corrections = new List<CorrectionItem>();

            foreach (var rule in rules)
            {
                if (System.Text.RegularExpressions.Regex.IsMatch(text, rule.Pattern))
                {
                    var matches = System.Text.RegularExpressions.Regex.Matches(text, rule.Pattern);
                    foreach (System.Text.RegularExpressions.Match match in matches)
                    {
                        corrections.Add(new CorrectionItem
                        {
                            Original = match.Value,
                            Corrected = rule.Replacement,
                            Reason = rule.Reason,
                            Type = rule.Type
                        });
                    }
                }
            }

            return corrections;
        }

        private CorrectionResult MergeCorrectionResults(List<CorrectionItem> codeCorrections, CorrectionResult aiCorrection, string preprocessedText)
        {
            var mergedCorrections = new List<CorrectionItem>();
            
            // 添加代码预处理发现的纠错
            mergedCorrections.AddRange(codeCorrections);

            // 添加AI纠错结果，避免重复
            if (aiCorrection.Success && aiCorrection.Corrections != null)
            {
                foreach (var aiItem in aiCorrection.Corrections)
                {
                    if (!mergedCorrections.Any(c => c.Original == aiItem.Original && c.Corrected == aiItem.Corrected))
                    {
                        mergedCorrections.Add(aiItem);
                    }
                }
            }

            // 底线保障机制：如果没有发现任何问题，添加格式优化建议
            if (mergedCorrections.Count == 0)
            {
                // 1. 检查段落格式
                var lines = preprocessedText.Split('\n');
                if (lines.Length < 3)
                {
                    mergedCorrections.Add(new CorrectionItem
                    {
                        Original = "整体格式",
                        Corrected = "建议将报告分为\"检查所见\"和\"诊断意见\"两个主要部分",
                        Reason = "当前报告结构较为简单，建议优化格式以提高可读性",
                        Type = CorrectionType.Format
                    });
                }

                // 2. 检查标点符号使用
                if (!preprocessedText.Contains("。") || !preprocessedText.Contains("，"))
                {
                    mergedCorrections.Add(new CorrectionItem
                    {
                        Original = "标点符号",
                        Corrected = "建议使用规范的中文标点符号（句号、逗号等）",
                        Reason = "规范使用标点符号可以提高报告的可读性",
                        Type = CorrectionType.Format
                    });
                }

                // 3. 检查医学术语规范
                var commonTerms = new Dictionary<string, string>
                {
                    { "稍高密度", "略高密度" },
                    { "略显模糊", "边界欠清" },
                    { "基本正常", "未见明显异常" }
                };

                foreach (var term in commonTerms)
                {
                    if (preprocessedText.Contains(term.Key))
                    {
                        mergedCorrections.Add(new CorrectionItem
                        {
                            Original = term.Key,
                            Corrected = term.Value,
                            Reason = "建议使用更规范的医学术语表达",
                            Type = CorrectionType.Terminology
                        });
                    }
                }

                // 4. 如果仍然没有任何建议，添加通用优化建议
                if (mergedCorrections.Count == 0)
                {
                    mergedCorrections.Add(new CorrectionItem
                    {
                        Original = "全文",
                        Corrected = "建议优化",
                        Reason = "建议复查以下方面：1. 术语规范性 2. 描述完整性 3. 格式规范性 4. 逻辑连贯性",
                        Type = CorrectionType.Expression
                    });
                }
            }
            
            // AI返回的纠正后文本已经是基于预处理文本的，所以我们直接用
            var finalText = aiCorrection.Success ? aiCorrection.CorrectedText : preprocessedText;

            // 如果AI没有修改文本，使用预处理后的文本
            if (string.IsNullOrWhiteSpace(finalText) || finalText == preprocessedText)
            {
                finalText = ApplyBasicFormatting(preprocessedText);
            }

            return new CorrectionResult
            {
                Success = true,
                OriginalText = CurrentReport.OriginalText,
                CorrectedText = finalText,
                Corrections = mergedCorrections,
                Summary = BuildCorrectionSummary(mergedCorrections, codeCorrections.Count)
            };
        }

        private string ApplyBasicFormatting(string text)
        {
            if (string.IsNullOrWhiteSpace(text)) return text;

            var lines = text.Split('\n', StringSplitOptions.RemoveEmptyEntries)
                            .Select(l => l.Trim())
                            .Where(l => !string.IsNullOrWhiteSpace(l))
                            .ToList();

            var result = new StringBuilder();
            
            // 如果文本没有明显的分段，尝试添加基本结构
            if (lines.Count > 0 && !text.Contains("检查所见") && !text.Contains("诊断意见"))
            {
                result.AppendLine("检查所见：");
                foreach (var line in lines)
                {
                    result.AppendLine($"    {line}");
                }
                result.AppendLine();
                result.AppendLine("诊断意见：");
                result.AppendLine("    建议结合临床。");
            }
            else
            {
                // 保持原有格式，但确保每行都有适当的缩进
                foreach (var line in lines)
                {
                    if (line.Contains("：") || line.EndsWith(":"))
                    {
                        result.AppendLine(line);
                    }
                    else
                    {
                        result.AppendLine($"    {line}");
                    }
                }
            }

            return result.ToString().Trim();
        }

        private string BuildCorrectionSummary(List<CorrectionItem> corrections, int codeCorrectionsCount)
        {
            var types = corrections.GroupBy(c => c.Type)
                                  .ToDictionary(g => g.Key, g => g.Count());
            
            var summary = new StringBuilder();
            summary.Append($"共发现 {corrections.Count} 处需要改进的地方。");
            
            if (codeCorrectionsCount > 0)
            {
                summary.Append($"其中代码预处理发现 {codeCorrectionsCount} 处，");
            }
            
            if (types.ContainsKey(CorrectionType.Logic))
                summary.Append($"逻辑问题 {types[CorrectionType.Logic]} 处，");
            if (types.ContainsKey(CorrectionType.Terminology))
                summary.Append($"术语规范 {types[CorrectionType.Terminology]} 处，");
            if (types.ContainsKey(CorrectionType.Format))
                summary.Append($"格式优化 {types[CorrectionType.Format]} 处，");
            if (types.ContainsKey(CorrectionType.Expression))
                summary.Append($"表达改进 {types[CorrectionType.Expression]} 处，");
            
            return summary.ToString().TrimEnd('，', ' ') + "。";
        }

        public async Task<CorrectionResult> CorrectMedicalReportAsync(string originalText)
        {
            // 先用DeepSeek，余额不足时自动切换Qwen
            var result = await _deepSeekService.CorrectMedicalReportAsync(originalText);
            if (!result.Success && result.ErrorMessage != null && result.ErrorMessage.Contains("余额不足"))
            {
                // 自动切换到Qwen
                return await _qwenCorrectionService.CorrectMedicalReportAsync(originalText);
            }
            return result;
        }
    }
} 